using System;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Diagnostics.HealthChecks;
using Microsoft.Extensions.Logging;
using Microsoft.OpenApi.Models;
using Volo.Abp;
using Volo.Abp.AspNetCore;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Serilog;
using Volo.Abp.Autofac;
using Volo.Abp.BackgroundJobs;
using Volo.Abp.Modularity;
using Volo.Abp.Swashbuckle;
using Microsoft.AspNetCore.Cors;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore.PostgreSql;
using MatrixConfiguration.HttpApi.Host.HealthChecks;
using OpenTelemetry.Exporter.Prometheus;

namespace Matrix.Configuration
{
    [DependsOn(
        typeof(MatrixConfigurationHttpApiModule),
        typeof(MatrixConfigurationEntityFrameworkCoreModule),
        typeof(AbpAutofacModule),
        typeof(AbpAspNetCoreModule),
        typeof(AbpAspNetCoreSerilogModule),
        typeof(AbpSwashbuckleModule),
        typeof(AbpBackgroundJobsModule)
    )]
    public class MatrixConfigurationHttpApiHostModule : AbpModule
    {
        public override void ConfigureServices(ServiceConfigurationContext context)
        {
            var configuration = context.Services.GetConfiguration();
            var hostingEnvironment = context.Services.GetHostingEnvironment();

            // 配置PostgreSQL数据库
            Configure<AbpDbContextOptions>(options =>
            {
                options.Configure(context =>
                {
                    context.UseNpgsql();
                });
            });

            ConfigureSwaggerServices(context, configuration);
            ConfigureCors(context, configuration);
            ConfigureHealthChecks(context);

            // 集成OpenTelemetry可观测性
            context.Services.AddMatrixOpenTelemetry(configuration);

          }

        public override void OnApplicationInitialization(ApplicationInitializationContext context)
        {
            var app = context.GetApplicationBuilder();
            var env = context.GetEnvironment();
            var configuration = context.GetConfiguration();

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseCorrelationId();
            app.UseStaticFiles();
            app.UseRouting();
            app.UseCors();

            app.UseSwagger();
            app.UseSwaggerUI(options =>
            {
                options.SwaggerEndpoint("/swagger/v1/swagger.json", "Matrix Configuration API");
            });

            app.UseAuditing();
            app.UseAbpRequestLocalization();
            app.UseUnitOfWork();

            // 添加Prometheus指标端点
            var prometheusEnabledRaw = configuration["OpenTelemetry:Metrics:PrometheusExporter:Enabled"];
            var prometheusEnabled = prometheusEnabledRaw == "true" || prometheusEnabledRaw == "True";
            Console.WriteLine($"[DEBUG] Host模块 - PrometheusEnabled原始值: '{prometheusEnabledRaw}', 解析后: {prometheusEnabled}");

            if (prometheusEnabled)
            {
                var prometheusEndpoint = configuration["OpenTelemetry:Metrics:PrometheusExporter:Endpoint"] ?? "/metrics";
                Console.WriteLine($"[DEBUG] Host模块 - 正在注册Prometheus端点: {prometheusEndpoint}");
                app.UseOpenTelemetryPrometheusScrapingEndpoint(prometheusEndpoint);
            }
            else
            {
                Console.WriteLine("[DEBUG] Host模块 - Prometheus端点未启用");
            }

            app.UseConfiguredEndpoints();

            // 添加健康检查端点
            app.UseHealthChecks("/health");
        }

        private static void ConfigureSwaggerServices(ServiceConfigurationContext context, IConfiguration configuration)
        {
            context.Services.AddAbpSwaggerGen(
                options =>
                {
                    options.SwaggerDoc("v1", new OpenApiInfo { Title = "Matrix Configuration API", Version = "v1" });
                    options.DocInclusionPredicate((docName, description) => true);
                    options.CustomSchemaIds(type => type.FullName);
                });
        }

        private static void ConfigureCors(ServiceConfigurationContext context, IConfiguration configuration)
        {
            context.Services.AddCors(options =>
            {
                options.AddDefaultPolicy(
                    builder =>
                    {
                        builder
                            .WithOrigins(
                                configuration["App:CorsOrigins"]
                                    ?.Split(",", StringSplitOptions.RemoveEmptyEntries)
                                    ?? Array.Empty<string>())
                            .WithExposedHeaders("*")
                            .SetIsOriginAllowedToAllowWildcardSubdomains()
                            .AllowAnyHeader()
                            .AllowAnyMethod();
                    });
            });
        }

        private static void ConfigureHealthChecks(ServiceConfigurationContext context)
        {
            context.Services.AddHealthChecks()
                .AddCheck<ConfigurationHealthCheck>("configuration");
        }
    }
}